/* $Id: imgflip.jquery.js 29 2009-10-22 19:58:19Z geraldb $

Unobtrusive Accessible jQuery image flips.

Supports:
	- Parent objects triggering flips on images (first child img or input[type='image'] found
	- Focus flips (for accessibility/tabbing)

Usage:
	Name your images with the proper scheme: <name>_off for "regular" state, <name>_on for "over" state.
	In your JavaScript use the syntax $('.rollOverName').imgflip();

Authors:
	bcurtis, gburns

TODO:
	Support "down" state?
	"active" state?
	Arbitrary states
*/

(function($) {
$.fn.imgflip = function() {
	var img_obj, src_parts, hasRolls, $trigger;

	var reg_match = /^(.*?)([^\/]+)_(on|off|down|active|selected)\.(\w{3,4})$/;

	var self = this;

	return $(this).each(function() {
		var $this = $(this);
		var img_obj;
		var $img_obj;
		// if the element has a src, use it
		// TODO: make sure these are img or input[type='image'] as opposed to something else with a src property?
		if ( this.src ) {
			img_obj = this;
		// otherwise find the first image or input[type='image'] found within the element
		// TODO: make it possible for the flip to not be the first image?
		} else {
			$('img, input[type=\'image\']', this).each(function() {
				if ( this.src.match(reg_match) ) {
					img_obj = this;
					return false;
				}
			});
		}

		if (!img_obj) return;
		$img_obj = $(img_obj);

		var src_parts = img_obj.src.match(reg_match);

		var hasRolls = false;
		var $trigger;

		if ( src_parts ) {
			this['mouseisdown'] = false;
			// Load images/image paths into object
			if ( !this[src_parts[1] + src_parts[2]] ) this[src_parts[1] + src_parts[2]] = [];

			this[src_parts[1] + src_parts[2]]['default'] = new Image();
			this[src_parts[1] + src_parts[2]]['default'].src = img_obj.src;

			this[src_parts[1] + src_parts[2]]['on'] = new Image();
			this[src_parts[1] + src_parts[2]]['on'].src = src_parts[1] + src_parts[2] + '_on.' + src_parts[4];

			// If the parent is an anchor tag, use that for the mouseover/focus trigger rather than the object itself
			if ( $img_obj.attr('type') == 'image' || img_obj.nodeName == 'A' ) {
				$trigger = $img_obj;
			} else {
				$trigger = $this;
			}

			$trigger
				.mouseover(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['on'].src))
				// Make sure we don't fire "out" functions too many times if they are clicking
				.mousedown(function(img_obj) {
					return function() {
						img_obj['mouseisdown'] = true;
					}
				}(img_obj))
				.click(function(img_obj) {
					return function() {
						img_obj['mouseisdown'] = false;
					}
				}(img_obj))
				.focus(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
						img_obj['hasfocus'] = true;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['on'].src))
				.mouseout(function(img_obj, flip_name) {
					return function() {
						if ( img_obj['hasfocus'] == false ) img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['default'].src))
				.blur(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
						img_obj['hasfocus'] = false;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['default'].src));
		}

		img_obj['mouseisdown'] = false;
		img_obj['hasfocus'] = false;
	});
}
})(jQuery);